import functools

from utils.log import Log
from utils.raw_obj import RawObject as Obj


# 2025/06/01 也门攻打美军尼米兹级艾森豪威尔航母,最后一张军事牌也要被戳破了吗?😄
# 独立的外交和强大的工业是衡量一个国家是否具有爆发潜力的两个因素,缺一不可.
# 战争的本质是经济与消耗,工业是关键.

class BitOp(object):
    BIT_ARRAY = [
        0, 1, 2, 2, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8,
        16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
        32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
        32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
        64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
        64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
        64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
        64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128
    ]

    @staticmethod
    def is_odd(val) -> bool:
        return bool(int(val) & 1)

    @staticmethod
    def is_even(val) -> bool:
        return not (int(val) & 1)

    @staticmethod
    def childs(val):
        left = int(val) << 1
        return left, left | 1

    @staticmethod
    def parent(val):
        return int(val) if int(val) == 1 else int(val) >> 1

    @staticmethod
    def middle(left, right):
        return left + ((right - left) >> 1)

    @staticmethod
    def right_most_1bit(val):
        # print(int(val) & (~int(val) + 1), int(val) & int(-val))
        return int(val) & int(-val)

    @staticmethod
    def ge2power(val):
        # function name means great and equal 2 power
        # ref: https://www.bilibili.com/video/BV1ch4y1Q7vd/?spm_id_from=333.999.0.0&vd_source=ad559e41b561d48861f70d0187e51e02
        # 00:06:13
        if val < 0:
            Log().simple_error("only support positive value")
        if val & (val - 1) == 0:
            return val
        # shift_i = 1
        # while ((val + 1) & val) != 0:
        #     val |= (val >> shift_i)
        #     shift_i <<= 1
        val |= val >> 1
        val |= val >> 2
        val |= val >> 4
        val |= val >> 8
        val |= val >> 16
        return val + 1

    @staticmethod
    def left_most_1bit(val):
        ge2power = BitOp.ge2power(val)
        if ge2power == val:
            return val
        return ge2power >> 1

    @staticmethod
    def right_most_1bit_index(val):
        ...

    @staticmethod
    def left_most_1bit_index(val):
        ...

    @staticmethod
    def swap(a, b):
        a ^= b
        b ^= a
        a ^= b
        return a, b

    @staticmethod
    def reverse_bits(val):
        # 顺序无关,逆序,无序都没关系
        val = ((val & 0xaaaaaaaa) >> 1) | ((val & 0x55555555) << 1)
        val = ((val & 0xcccccccc) >> 2) | ((val & 0x33333333) << 2)
        val = ((val & 0xf0f0f0f0) >> 4) | ((val & 0x0f0f0f0f) << 4)
        val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8)
        val = ((val & 0xffff0000) >> 16) | ((val & 0x0000ffff) << 16)
        return val

    @staticmethod
    def one_number(val):
        # 顺序不能乱
        # ref: https://www.bilibili.com/video/BV1ch4y1Q7vd/?spm_id_from=autoNext&vd_source=ad559e41b561d48861f70d0187e51e02
        # 43:04 居然直接问 天工AI.编程助理 也能答出来
        val = (val & 0x55555555) + ((val >> 1) & 0x55555555)
        val = (val & 0x33333333) + ((val >> 2) & 0x33333333)
        val = (val & 0x0f0f0f0f) + ((val >> 4) & 0x0f0f0f0f)
        val = (val & 0x00ff00ff) + ((val >> 8) & 0x00ff00ff)
        val = (val & 0x0000ffff) + ((val >> 16) & 0x0000ffff)
        return val

    @staticmethod
    def one_number2(val):
        number = 1
        while val & (val - 1):
            number += 1
            val &= val - 1
        return 0 if val == 0 else number

    @staticmethod
    def add(a, b):
        # b不能是负数
        result = a
        while b != 0:
            result ^= b
            b = (a & b) << 1
        return result

    @staticmethod
    def neg(val):
        return BitOp.add(~val, 1)

    @staticmethod
    def minus(a, b):
        """
        deprecated
        # 无法得到正确答案
        """
        return BitOp.add(a, BitOp.neg(b))


if __name__ == '__main__':
    print(BitOp.is_odd(Obj(371)))
    print(BitOp.is_even(446))
    print(BitOp.childs(31))
    print(BitOp.parent(137))
    print(bin(4364), bin(BitOp.right_most_1bit(4364)))

    print(BitOp.swap(3592, -2164))

    print(BitOp.right_most_1bit(1920))
    print(BitOp.left_most_1bit(1920))

    print(bin(12345678))
    print(bin(BitOp.reverse_bits(12345678)))

    print(BitOp.one_number(12345678))
    print(BitOp.one_number2(12345678))

    print(BitOp.add(38, 19))
    print(BitOp.minus(34, 18), bin(34), bin(-18))
